﻿using System;
using System.Configuration;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using IntegrationTests.Core.Resources;
using Selenium;
using Xunit;


namespace IntegrationTests.Core.Websites
{
	public class WebsiteBase
    {
        protected ISelenium Selenium = StartSelenium();

        public bool IsStarted
        {
            get { return Selenium != null; }
        }

        private static ISelenium StartSelenium()
        {
            string seleniumServerHost = ConfigurationManager.AppSettings["SeleniumServerHost"];
            int seleniumServerPort = Int32.Parse(ConfigurationManager.AppSettings["SeleniumServerPort"]);
            string seleniumWebBrowser = ConfigurationManager.AppSettings["SeleniumWebBrowser"];
            string siteUrl = ConfigurationManager.AppSettings["SiteUrl"];

        	var v = new TimeoutHttpCommandProcessor(seleniumServerHost, seleniumServerPort, seleniumWebBrowser, siteUrl);
        	ISelenium selenium = new DefaultSelenium(v);
            selenium.Start();
            selenium.SetTimeout(TimeoutConfiguration.Selenium);
            selenium.WindowMaximize();
        	return selenium;
        }

        public void GoBack()
        {
            Selenium.GoBack();
            WaitForPageToLoad();
        }

        public void Stop()
        {
            try
            {
            	Selenium.Stop();
            }
            catch
            {
            }
            finally
            {
                Selenium = null;
            }
        }

        public void LogOn(string login, string password)
        {
            OpenPage("/");
            TypeLogin(login);
            TypePassword(password);
            ClickLogOn();
        }

        public void ClickLogOn()
        {
            ClickElement(Locators.EnterButtonLocator);
            WaitForPageToLoad();
        }

        public void TypePassword(string password)
        {
            Type(Locators.PasswordInputLocator, password);
        }

        public void TypeLogin(string login)
        {
            Type(Locators.LoginInputLocator, login);
        }

        public void ClearCookies()
        {
            OpenPage("/");
            Selenium.DeleteAllVisibleCookies();
        }

        public void ClickElement(string xpath)
        {
            try
            {
                TryClick(xpath);
            }
            catch (Exception)
            {
                Thread.Sleep(2000);
                TryClick(xpath);
            }
        }

        private void TryClick(string xpath)
        {
            if (Selenium.IsVisible(xpath) == false)
                throw new SeleniumException("Попытка нажать на скрытый элемент!");
            Selenium.Click(xpath);
        }

        public void VerifyColorTask()
        {
            Selenium.IsVisible("//div[contains(@class,'red-task')]");
        }

        public void OpenPage(string url)
        {
            Assert.True(IsStarted);
            Selenium.Open(url);
            WaitForPageToLoad();
        }

        public void WaitForPageToLoad()
        {
            Selenium.WaitForPageToLoad(TimeoutConfiguration.Page);
            if (Selenium.IsTextPresent("Server Error"))
            {
                string exceptionText = Selenium.GetText("//h2");

                throw new SeleniumException("Server error! " + exceptionText);
            }
        }

        public void VerifyTextPresent(string text)
        {
            Assert.True(Selenium.IsTextPresent(text), string.Format("На странице не найдена строка: '{0}'", text));
        }


        public void VerifyNoText(string text)
        {
            Assert.False(Selenium.IsTextPresent(text), string.Format("На странице не должна присутствовать строка: '{0}'", text));
        }

        public void VerifyTitle(string expected)
        {
            Assert.Equal(expected, Selenium.GetTitle());
        }

        internal void Type(string locator, string text)
        {
            try
            {
                Selenium.Focus(locator);
                Selenium.Type(locator, text);
            }
            catch (Exception)
            {
                Thread.Sleep(2000);
                Selenium.Focus(locator);
                Selenium.Type(locator, text);
            }
        }

        internal void Select(string locator, string value)
        {
            Selenium.Select(locator, value);
        }

        private string GetBrowserTitle()
        {
            return Selenium.GetTitle() + " - Google Chrome";
        }

        public string GetCurrentAuthorizationCookie()
        {
            return Selenium.GetCookie();
        }

    }
}